import com.cloudgarden.resource.SWTResourceManager;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
//import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class UserGUI extends org.eclipse.swt.widgets.Composite {

	{
		//Register as a resource user - SWTResourceManager will
		//handle the obtaining and disposing of resources
		SWTResourceManager.registerResourceUser(this);
	}
	
	private Button button1;
	private Text text1;
	static ServerSocket serverSocket=null;
	private Button minus;
	private Button not;
	private Button l_bracket;
	private Button r_bracket;
	private Button or;
	private Button and;
	private static List list1;

	ArrayList<String> tags;
	private CLabel label3;
	private Label label2;
	private Label label1;
	private List list2;
	
	static Socket clientSocket;
	static boolean to_run=true;

	static BufferedReader in;
	static PrintWriter out;
	
	 public  int includesOperatorsNotBetweenBrackets(String str)
	    {
	    	
	    	for (int i=0;i<str.length();i++)
	    	{
	    		if((str.charAt(i)=='&' || str.charAt(i)=='|' || str.charAt(i)=='-') && !isBetweenBrackets(str,i))
	    		{
	    			return i;
	    		}
	    	}
	    	return -1;
	    }
	    
	    private boolean isBetweenBrackets(String str,int index)
	    {
	    	if(index==str.length()-1)
	    		return false;
	    	
	    	boolean flag1=false;
	    	for(int i=index+1;i<str.length();i++)
	    	{
	    		if(str.charAt(i)=='(')
	    			return false;
	    		if(str.charAt(i)==')')
	    		{
	    			flag1=true;
	    			break;
	    		}
	    	}
	    	
	    	if(!flag1)
	    		return false;
	    	
	    	int i;
	    	for(i=0;i<index;i++)
	    	{
	    		if(str.charAt(i)==')')
	    			return false;
	    		if(str.charAt(i)=='(')
	    		{
	    			return true;
	    		}
	    	}
	    	
	    	return false;
	    }
	public ArrayList<ArrayList<String>> getFileAndTagsLists()
	{
	
		Tag tag;
		ArrayList<String> files=new ArrayList<String>();
		ArrayList<ArrayList<String>> result=new ArrayList<ArrayList<String>>();
		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
		Session session = sessionFactory.openSession();

		Query query = session.createQuery("from Tag");

		java.util.List <Tag>list = query.list();
		Iterator<Tag> it=list.iterator();

		//preparing a list of all files in db
		while (it.hasNext()){
		 tag=it.next();
		 if(!files.contains(tag.getFilePath()))
		 files.add(tag.getFilePath());
		 }
		Tag temp_tag;
		for(int i=0;i<files.size();i++)
		{
			ArrayList<String> tags_of_file=new ArrayList<String>();
			tags_of_file.add(files.get(i));
			it=list.iterator();
			while (it.hasNext()){
				 temp_tag=it.next();
				 if(temp_tag.getFilePath().equals(files.get(i)))
				 tags_of_file.add(temp_tag.getTag());
				 }
			
			result.add(tags_of_file);
				
		}
		return result;
	}
	public String[] basic_intersection(ArrayList<ArrayList<String>> map,String [] labels)
	{
		ArrayList<String> results=new ArrayList<String>();
		for(int i=0;i<map.size();i++)
		{
			String file=map.get(i).get(0);
			java.util.List<String> sub_list=map.get(i).subList(1, map.get(i).size());
			boolean appears=true;
			for(int j=0;j<labels.length;j++)
			{
				if(!sub_list.contains(labels[j]))
				{
					appears=false;
					break;
				}
			}
			
			if(appears)
				results.add(file);
		}
		String[] temp_result=new String[results.size()];
		return results.toArray(temp_result);	
	}
	
	public String[] union(String[] files1,String [] files2)
	{
		ArrayList<String> results=new ArrayList<String>();
		for(int i=0;i<files1.length;i++)
		{
			results.add(files1[i]);
		}
		for(int i=0;i<files2.length;i++)
		{
			if(!results.contains(files2[i]))
			results.add(files2[i]);
		}
		
		String[] temp_result=new String[results.size()];
		return results.toArray(temp_result);	
	}
	public String[] substraction(String[] files1,String [] files2)
	{System.out.println("in d "+files1.length+" "+files2.length);
		ArrayList<String> results=new ArrayList<String>();
		for(int i=0;i<files1.length;i++)
		{
			results.add(files1[i]);
		}
		
		String[] to_erase=intersection(files1,files2);
		
		for(int i=0;i<to_erase.length;i++)
		{
			results.remove(to_erase[i]);
		}
		
		String[] temp_result=new String[results.size()];
		return results.toArray(temp_result);	
	}
	public String[] intersection(String[] files1,String [] files2)
	{
		ArrayList<String> results=new ArrayList<String>();
		for(int i=0;i<files1.length;i++)
		{
			for(int j=0;j<files2.length;j++)
				if(files2[j].equals(files1[i]))
				{
					results.add(files1[i]);
					break;
				}
		}
		String[] temp_result=new String[results.size()];
		return results.toArray(temp_result);	
	}
	public String[] getResult(ArrayList<ArrayList<String>>  map,String qu)
	{
		if(qu.indexOf(')')<0 && qu.indexOf('~')<0)
		{
			String elems[]=qu.split("&");
			return basic_intersection(map,elems);
		}
		else if(qu.indexOf(')')==qu.lastIndexOf(')') && qu.indexOf('~')<0)
		{
			qu=qu.substring(qu.indexOf('(')+1,qu.lastIndexOf(')'));
			String elems[]=qu.split("&");
			return basic_intersection(map,elems);
		}
		else
		{
			if(qu.charAt(0)=='~')
			{
				int index=includesOperatorsNotBetweenBrackets(qu);
				if(index<0)
				{	String sub=qu.substring(1);
					String[] files=new String[map.size()];
					for(int j=0;j<files.length;j++)
					{
						files[j]=map.get(j).get(0);

					}
					return substraction(files,getResult(map,sub));
				}
				else
				{
					String left=qu.substring(0,index);
					String right=qu.substring(index+1,qu.length());
					
					if(left.charAt(0)=='(' && left.charAt(1)=='(' && left.charAt(left.length()-1)==')' && left.charAt(left.length()-2)==')' )	
						left=left.substring(1,left.length()-1);
					if(right.charAt(0)=='(' && right.charAt(1)=='(' && right.charAt(right.length()-1)==')' && right.charAt(right.length()-2)==')' )	
						right=right.substring(1,right.length()-1);
					
					if(qu.charAt(index)=='|')
					{
						return union(getResult(map,right),getResult(map,left));
					}
					if(qu.charAt(index)=='&')
					{
						return intersection(getResult(map,right),getResult(map,left));
					}
					if(qu.charAt(index)=='-')
					{
						
						return substraction(getResult(map,left),getResult(map,right));
					}
				}
			}
			else
			{
			int count=0;
			for(int i=0;i<qu.length();i++)
			{
				if(qu.charAt(i)=='(')
					count++;
				if(qu.charAt(i)==')')
					count--;
				if(count==0)
				{System.out.println("i is"+i);
					String left_side=qu.substring(0,i+1);
					String right_side=qu.substring(i+2,qu.length());
					System.out.println("left "+left_side);
					System.out.println("right "+right_side);
					
					if(left_side.charAt(0)=='(' && left_side.charAt(1)=='(' && left_side.charAt(left_side.length()-1)==')' && left_side.charAt(left_side.length()-2)==')' )	
						left_side=left_side.substring(1,left_side.length()-1);
					if(right_side.charAt(0)=='(' && right_side.charAt(1)=='(' && right_side.charAt(right_side.length()-1)==')' && right_side.charAt(right_side.length()-2)==')' )	
						right_side=right_side.substring(1,right_side.length()-1);
					
					if(qu.charAt(i+1)=='|')
					{
						/*if(left_side.charAt(0)=='(' && left_side.charAt(1)=='(' && left_side.charAt(left_side.length()-1)==')' && left_side.charAt(left_side.length()-2)==')' && right_side.charAt(0)=='(' && right_side.charAt(1)=='(' && right_side.charAt(left_side.length()-1)==')' && right_side.charAt(left_side.length()-2)==')')
						{		
							return union(getResult(map,right_side.substring(1,right_side.length()-1)),getResult(map,left_side.substring(1,left_side.length()-1)));
						}
						else if(left_side.charAt(0)=='(' && left_side.charAt(1)=='(' && left_side.charAt(left_side.length()-1)==')' && left_side.charAt(left_side.length()-2)==')' )	
						{
							return union(getResult(map,right_side),getResult(map,left_side.substring(1,left_side.length()-1)));
						}
						else if(right_side.charAt(0)=='(' && right_side.charAt(1)=='(' && right_side.charAt(right_side.length()-1)==')' && right_side.charAt(right_side.length()-2)==')' )	
						{
							return union(getResult(map,left_side),getResult(map,right_side.substring(1,right_side.length()-1)));
						}
						else*/
							return union(getResult(map,right_side),getResult(map,left_side));
					}
					if(qu.charAt(i+1)=='&')
					{
						return intersection(getResult(map,right_side),getResult(map,left_side));
					}
					if(qu.charAt(i+1)=='-')
					{
						
						return substraction(getResult(map,left_side),getResult(map,right_side));
					}
					/*if(qu.charAt(i+1)=='~')
					{
						System.out.println("not");
					
						int index=includesOperatorsNotBetweenBrackets(qu);
						
					}*/
					break;
				}
				
			}
			}
		}
		return null;
	}
	/**
	* Auto-generated main method to display this 
	* org.eclipse.swt.widgets.Composite inside a new Shell.
	*/
	
	public static void main(String[] args) {
		try {
			serverSocket = new ServerSocket(4444);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		Thread thread=new Thread(new Runnable(){

			@Override
			public void run() {
				// TODO Auto-generated method stub
				 try {
					clientSocket=serverSocket.accept();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} 
				while(to_run){
					try {
						
						System.out.println("will !"); 
						
						
					   
					    out=new PrintWriter(clientSocket.getOutputStream(),true);
					    in=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

					   System.out.println(in.readLine()+"gtfgh");
					    System.out.println("will update!"); 
					    out.write("jgh");
					    
						
				Display.getDefault().asyncExec(new Runnable(){

					@Override
					public void run() {
						// TODO Auto-generated method stub
						

						SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
						Session session = sessionFactory.openSession();
						Query query = session.createQuery("from Tag");
								java.util.List<Tag> list = query.list();
								Iterator<Tag> it=list.iterator();
								list1.removeAll();
								while (it.hasNext()){
								 Tag tag_name=it.next();
								 if(list1.indexOf(tag_name.getTag()) < 0)
								 list1.add(tag_name.getTag());
								}

							    
							
					}});
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
					}
				
				
			}});
		thread.start();
		showGUI();
	}
	
	/**
	* Overriding checkSubclass allows this class to extend org.eclipse.swt.widgets.Composite
	*/	
	protected void checkSubclass() {
	}
	
	/**
	* Auto-generated method to display this 
	* org.eclipse.swt.widgets.Composite inside a new Shell.
	*/
	public static void showGUI() {
		Display display = Display.getDefault();
		Shell shell = new Shell(display,SWT.MIN);
		
		shell.addDisposeListener(new DisposeListener(){

			@Override
			public void widgetDisposed(DisposeEvent arg0) {
				// TODO Auto-generated method stub
				try {
					System.out.println("dsa");
					//clientSocket.close();
					serverSocket.close();
					to_run=false;
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}});
		UserGUI inst = new UserGUI(shell, SWT.NULL);
		Point size = inst.getSize();
		shell.setLayout(new FillLayout());
		shell.layout();
		if(size.x == 0 && size.y == 0) {
			inst.pack();
			shell.pack();
		} else {
			Rectangle shellBounds = shell.computeTrim(0, 0, size.x, size.y);
			shell.setSize(shellBounds.width, shellBounds.height);
		}
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
	}

	public UserGUI(org.eclipse.swt.widgets.Composite parent, int style) {
		super(parent, style);
		initGUI();
	}

	private void initGUI() {
		try {
			FormLayout thisLayout = new FormLayout();
			this.setLayout(thisLayout);
			this.setSize(689, 292);
			{
				FormData label3LData = new FormData();
				label3LData.left =  new FormAttachment(0, 1000, 386);
				label3LData.top =  new FormAttachment(0, 1000, 3);
				label3LData.width = 291;
				label3LData.height = 23;
				label3 = new CLabel(this, SWT.H_SCROLL | SWT.BORDER);
				label3.setLayoutData(label3LData);
				label3.setForeground(SWTResourceManager.getColor(0, 0, 255));
			
			}
			{
				label2 = new Label(this, SWT.NONE);
				FormData label2LData = new FormData();
				label2LData.left =  new FormAttachment(0, 1000, 317);
				label2LData.top =  new FormAttachment(0, 1000, 12);
				label2LData.width = 63;
				label2LData.height = 15;
				label2.setLayoutData(label2LData);
				label2.setText("Files results:");
			}
			{
				label1 = new Label(this, SWT.NONE);
				FormData label1LData = new FormData();
				label1LData.left =  new FormAttachment(0, 1000, 43);
				label1LData.top =  new FormAttachment(0, 1000, 12);
				label1LData.width = 59;
				label1LData.height = 15;
				label1.setLayoutData(label1LData);
				label1.setText("Select tags:");
			}
			{
				FormData list2LData = new FormData();
				list2LData.left =  new FormAttachment(0, 1000, 317);
				list2LData.top =  new FormAttachment(0, 1000, 32);
				list2LData.width = 338;
				list2LData.height = 171;
				list2 = new List(this, SWT.BORDER);
				list2.setLayoutData(list2LData);
			}
			{
				l_bracket = new Button(this, SWT.PUSH | SWT.CENTER);
				FormData l_bracketLData = new FormData();
				l_bracketLData.left =  new FormAttachment(0, 1000, 270);
				l_bracketLData.top =  new FormAttachment(0, 1000, 127);
				l_bracketLData.width = 23;
				l_bracketLData.height = 25;
				l_bracket.setLayoutData(l_bracketLData);
				l_bracket.setText(")");
			}
			{
				r_bracket = new Button(this, SWT.PUSH | SWT.CENTER);
				FormData r_bracketLData = new FormData();
				r_bracketLData.left =  new FormAttachment(0, 1000, 232);
				r_bracketLData.top =  new FormAttachment(0, 1000, 127);
				r_bracketLData.width = 23;
				r_bracketLData.height = 25;
				r_bracket.setLayoutData(r_bracketLData);
				r_bracket.setText("(");
			}
			{
				not = new Button(this, SWT.PUSH | SWT.CENTER);
				FormData notLData = new FormData();
				notLData.left =  new FormAttachment(0, 1000, 270);
				notLData.top =  new FormAttachment(0, 1000, 90);
				notLData.width = 23;
				notLData.height = 25;
				not.setLayoutData(notLData);
				not.setText("~");
				

				not.addSelectionListener(new SelectionListener(){

					@Override
					public void widgetDefaultSelected(SelectionEvent arg0) {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void widgetSelected(SelectionEvent arg0) {
						// TODO Auto-generated method stub
						text1.setText(text1.getText()+"~");
					}});	
			}
			{
				minus = new Button(this, SWT.PUSH | SWT.CENTER);
				FormData minusLData = new FormData(23, 25);
				minusLData.left =  new FormAttachment(0, 1000, 232);
				minusLData.top =  new FormAttachment(0, 1000, 90);
				minusLData.width = 23;
				minusLData.height = 25;
				minus.setLayoutData(minusLData);
				minus.setText("-");
				minus.setSize(23, 25);
				

				minus.addSelectionListener(new SelectionListener(){

					@Override
					public void widgetDefaultSelected(SelectionEvent arg0) {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void widgetSelected(SelectionEvent arg0) {
						// TODO Auto-generated method stub
						text1.setText(text1.getText()+"-");
					}});	
			}
			{
				or = new Button(this, SWT.PUSH | SWT.CENTER);
				FormData orLData = new FormData();
				orLData.left =  new FormAttachment(0, 1000, 270);
				orLData.top =  new FormAttachment(0, 1000, 53);
				orLData.width = 23;
				orLData.height = 25;
				or.setLayoutData(orLData);
				or.setText("V");
				
				or.addSelectionListener(new SelectionListener(){

					@Override
					public void widgetDefaultSelected(SelectionEvent arg0) {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void widgetSelected(SelectionEvent arg0) {
						// TODO Auto-generated method stub
						
						/*
						String[] selections=list1.getSelection();
						String query="(";
						for(int i=0;i<selections.length;i++)
						{
							if(i>0)
							query+=" && "+selections[i];
							else
							query+=selections[i];
						}
						query+=")";
						query+=" || ";
						text1.setText(text1.getText()+" "+query);
				*/
						text1.setText(text1.getText()+"|");
					
					}});
			}
			{
				and = new Button(this, SWT.PUSH | SWT.CENTER);
				FormData andLData = new FormData(23, 25);
				andLData.left =  new FormAttachment(0, 1000, 232);
				andLData.top =  new FormAttachment(0, 1000, 53);
				andLData.width = 23;
				andLData.height = 25;
				and.setLayoutData(andLData);
				and.setText("^");
				and.setSize(23, 25);
				
				and.addSelectionListener(new SelectionListener(){

					@Override
					public void widgetDefaultSelected(SelectionEvent arg0) {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void widgetSelected(SelectionEvent arg0) {
						// TODO Auto-generated method stub
						text1.setText(text1.getText()+"&");
					}});			}
			{
				FormData list1LData = new FormData();
				list1LData.left =  new FormAttachment(0, 1000, 43);
				list1LData.top =  new FormAttachment(0, 1000, 32);
				list1LData.width = 131;
				list1LData.height = 171;
				list1 = new List(this, SWT.MULTI | SWT.V_SCROLL | SWT.BORDER);
				list1.setLayoutData(list1LData);
			
				list1.addKeyListener(new KeyListener(){

					@Override
					public void keyPressed(KeyEvent arg0) {
						// TODO Auto-generated method stub
						if(arg0.character=='\r')
						{
							
							String[] selections=list1.getSelection();
							String query="(";
							for(int i=0;i<selections.length;i++)
							{
								if(i>0)
								query+="&"+selections[i];
								else
								query+=selections[i];
							}
							query+=")";
							
							text1.setText(text1.getText()+""+query);
						}
					}

					@Override
					public void keyReleased(KeyEvent arg0) {
						// TODO Auto-generated method stub
						
					}});

					
				SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
				Session session = sessionFactory.openSession();
				Query query = session.createQuery("from Tag");

				
				java.util.List<Tag> list = query.list();
				Iterator<Tag> it=list.iterator();

				while (it.hasNext()){
				 Tag tag_name=it.next();
				 if(list1.indexOf(tag_name.getTag()) < 0)
				 list1.add(tag_name.getTag());
				}

				
			}
			{
				button1 = new Button(this, SWT.PUSH | SWT.CENTER);
				FormData button1LData = new FormData();
				button1LData.left =  new FormAttachment(0, 1000, 499);
				button1LData.top =  new FormAttachment(0, 1000, 219);
				button1LData.width = 49;
				button1LData.height = 25;
				button1.setLayoutData(button1LData);
				button1.setText("submit");
				
				button1.addSelectionListener(new SelectionListener(){

					@Override
					public void widgetDefaultSelected(SelectionEvent arg0) {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void widgetSelected(SelectionEvent arg0) {
						// TODO Auto-generated method stub
						String input=text1.getText();
						
						label3.setText(text1.getText());
						label3.setToolTipText(label3.getText());
						System.out.println("the list is: ");
						ArrayList<ArrayList<String>> r=getFileAndTagsLists();
						System.out.println(r.size());
						String[] files=getResult(getFileAndTagsLists(),input);
						list2.removeAll();
						for(int i=0;i<files.length;i++)
						list2.add(files[i]);
					/*	System.out.println("hiiiiiiii");
						Tag user;

						SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
						Session session = sessionFactory.openSession();

						Query query = session.createQuery("from User as u where u.firstName like '"+input+"'");

						java.util.List <Tag>list = query.list();
						Iterator<Tag> it=list.iterator();

						while (it.hasNext()){
						 user=it.next();
						 System.out.println("id: \t\t"+user.getUserId());
						 System.out.println("age: \t\t"+user.getAge());
						 System.out.println("first name: \t"+user.getFirstName());
						 System.out.println("last name: \t"+user.getLastName());
						 System.out.println("email: \t\t"+user.getEmail());*/
						//}

						text1.setText("");
					}});
			}
			{
				text1 = new Text(this, SWT.H_SCROLL | SWT.BORDER);
				FormData text1LData = new FormData();
				text1LData.left =  new FormAttachment(0, 1000, 49);
				text1LData.top =  new FormAttachment(0, 1000, 219);
				text1LData.width = 417;
				text1LData.height = 31;
				text1.setLayoutData(text1LData);

			}
			this.layout();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


}
